import { defineComponent, PropType, App, cloneVNode } from 'vue'
import BorderLight from '../border-light'
import Icon from '../icon'
import { getComponent, hasElemnt, flattenChildren } from '../_util/props-util'

const Card = defineComponent({
  name: 'x-card',
  props: {
    prefixCls: { default: 'x-card' },
    title: String,
    icon: Object,
    bordered: { default: true },
    hoverable: Boolean,
    closable: Boolean,
    contentClass: [Object, String, Array],
    contentStyle: [Object, String],
    footerClass: [Object, String, Array],
    footerStyle: [Object, String],
    headerClass: [Object, String, Array],
    headerStyle: [Object, String],
    size: String as PropType<'small' | 'medium' | 'large' | 'huge'>,
  },
  slots: ['title', 'cover', 'header', 'header-extra', 'default', 'footer'],
  emits: ['close'],
  directives: {
    [BorderLight.name]: BorderLight
  },
  setup(props, { emit, slots }) {

    function close(e: MouseEvent) {
      e.stopPropagation()
      e.preventDefault()
      emit('close')
    }

    return vm => {
      const { prefixCls, size, closable, contentClass, footerClass, headerClass, icon } = props
      const cls = [prefixCls, {
        [`${prefixCls}-bordered`]: props.bordered,
        [`${prefixCls}-hoverable`]: props.hoverable,
        [`${prefixCls}-${size}`]: size
      }]

      const coverNode = slots.cover?.()
      const titleNode = getComponent(vm, 'title')
      const closeNode = closable ? <Icon class={`${prefixCls}_close`} type='cross' onClick={close} /> : undefined
      const contentNode = slots.default?.()
      const footerNode = slots.footer?.()
      
      const iconNode = flattenChildren(getComponent(vm, 'icon'))[0]
      const headerExtraNode = slots['header-extra']?.()
      const headerNode = (
        slots.header
          ? <div class={[`${prefixCls}_header`, headerClass]}>{ slots.header?.() }</div>
          : (
            <div class={`${prefixCls}_header`} style={props.headerStyle}>
              { hasElemnt(iconNode) && cloneVNode(iconNode, { class: `${prefixCls}_icon` }) }
              <div class={`${prefixCls}_title`}>{ titleNode }</div>
              { headerExtraNode && <div class={`${prefixCls}_header_extra`}>{ headerExtraNode }</div> }
              { closeNode }
            </div>
          )
      )

      return (
        <div class={cls} v-border-light={{ borderGradientSize: 160, bgColor: null }}>
          { hasElemnt(coverNode) && <div class={`${prefixCls}_cover`}>{ coverNode }</div> }
          { headerNode }
          { hasElemnt(contentNode) && <div class={[`${prefixCls}_content`, contentClass]} style={props.contentStyle}>{ contentNode }</div> }
          { hasElemnt(footerNode) && <div class={[`${prefixCls}_footer`, footerClass]} style={props.footerStyle}>{ footerNode }</div> }
        </div>
      )
    }
  }
})

Card.install = (app: App) => {
  app.component(Card.name, Card)
}

export default Card